#!/usr/bin/env bash
set -euo pipefail

# ========= 可调参数（保持与 2核4G 服务器匹配） =========
MYSQL_IMAGE="${MYSQL_IMAGE:-mysql:8.0}"
CONTAINER_NAME="${CONTAINER_NAME:-mysql}"
DATA_DIR="${DATA_DIR:-/srv/mysql/data}"
CONF_DIR="${CONF_DIR:-/srv/mysql/conf.d}"
LOG_DIR="${LOG_DIR:-/srv/mysql/logs}"
BACKUP_DIR="${BACKUP_DIR:-/srv/backup}"
HOST_PORT="${HOST_PORT:-3306}"
INNODB_BUFFER_POOL_SIZE="${INNODB_BUFFER_POOL_SIZE:-2G}"
INNODB_LOG_FILE_SIZE="${INNODB_LOG_FILE_SIZE:-256M}"
MAX_CONNECTIONS="${MAX_CONNECTIONS:-200}"
BINLOG_EXPIRE_SECONDS="${BINLOG_EXPIRE_SECONDS:-2592000}"  # 30天
HEALTH_INTERVAL="${HEALTH_INTERVAL:-10s}"
HEALTH_TIMEOUT="${HEALTH_TIMEOUT:-3s}"
HEALTH_RETRIES="${HEALTH_RETRIES:-5}"

# 资源限制（2核4G）
CPUS="${CPUS:-2}"
CPUSET="${CPUSET:-0,1}"
MEM_LIMIT="${MEM_LIMIT:-3g}"           # 给容器3G，留1G给系统
MEM_RESERVATION="${MEM_RESERVATION:-2g}"
MEM_SWAP="${MEM_SWAP:-3g}"             # 不额外可用swap
NOFILE_SOFT="${NOFILE_SOFT:-65535}"
NOFILE_HARD="${NOFILE_HARD:-65535}"

ROOT_PASSWORD="123456"

# ========= 参数解析（可选） =========
while [[ $# -gt 0 ]]; do
  case "$1" in
    --root-password)
      ROOT_PASSWORD="${2:-}"; shift 2;;
    --port)
      HOST_PORT="${2:-3306}"; shift 2;;
    --data-dir)
      DATA_DIR="${2:-/srv/mysql/data}"; shift 2;;
    --image)
      MYSQL_IMAGE="${2:-mysql:8.0}"; shift 2;;
    *)
      echo "未知参数: $1"; exit 2;;
  esac
done

echo "MySQL root 密码已设定（固定值）"

echo "==> 安装 Docker（如未安装）"
if ! command -v docker >/dev/null 2>&1; then
  if command -v yum >/dev/null 2>&1; then
    sudo yum makecache fast || true
    sudo yum -y install yum-utils device-mapper-persistent-data lvm2 || true
    sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo || true
    sudo yum -y install docker-ce docker-ce-cli containerd.io
  elif command -v apt-get >/dev/null 2>&1; then
    sudo apt-get update
    sudo apt-get -y install ca-certificates curl gnupg lsb-release
    curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") $(. /etc/os-release; echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
    sudo apt-get update
    sudo apt-get -y install docker-ce docker-ce-cli containerd.io
  else
    echo "未支持的包管理器，请手动安装 Docker 后重试"; exit 1
  fi
fi

echo "==> 启动并设置 Docker 开机自启"
sudo systemctl enable --now docker

echo "==> 准备数据目录、配置与日志目录"
sudo mkdir -p "${DATA_DIR}" "${CONF_DIR}" "${LOG_DIR}" "${BACKUP_DIR}"
# 提前设置较宽权限；容器内再校正
sudo chown -R root:root "${DATA_DIR}" "${CONF_DIR}" "${LOG_DIR}" "${BACKUP_DIR}"
sudo chmod -R 0755 "${DATA_DIR}" "${CONF_DIR}" "${LOG_DIR}" "${BACKUP_DIR}"

# 创建客户端配置文件（健康检查需要）
echo "==> 创建客户端配置文件"
cat <<EOF | sudo tee "${CONF_DIR}/client.cnf" >/dev/null
[client]
user=root
password=${ROOT_PASSWORD}
host=127.0.0.1
port=3306
EOF

echo "==> 调整内核 Swap 倾向，降低换页"
if command -v sysctl >/dev/null 2>&1; then
  sudo sysctl -w vm.swappiness=1
  if ! grep -q '^vm.swappiness=' /etc/sysctl.conf 2>/dev/null; then
    echo "vm.swappiness=1" | sudo tee -a /etc/sysctl.conf >/dev/null
  else
    sudo sed -i 's/^vm.swappiness=.*/vm.swappiness=1/' /etc/sysctl.conf
  fi
fi

echo "==> 拉取镜像 ${MYSQL_IMAGE}"
sudo docker pull "${MYSQL_IMAGE}"

# 如已有容器，先备份后安全重建（不删卷）
if sudo docker ps -a --format '{{.Names}}' | grep -qx "${CONTAINER_NAME}"; then
  echo "==> 发现已存在容器 ${CONTAINER_NAME}，尝试备份"
  if sudo docker ps --format '{{.Names}}' | grep -qx "${CONTAINER_NAME}"; then
    # 在线备份
    set +e
    sudo docker exec -i "${CONTAINER_NAME}" sh -lc 'mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" --all-databases --single-transaction --routines --events' > "${BACKUP_DIR}/mysql-pre-rebuild-$(date +%F-%H%M%S).sql"
    set -e
    echo "==> 备份完成或跳过（如失败不会中断）"
    sudo docker stop "${CONTAINER_NAME}" || true
  fi
  sudo docker rm "${CONTAINER_NAME}" || true
fi

# 预写一个最小配置（可自行追加.cnf）
cat <<'EOF' | sudo tee "${CONF_DIR}/99-tuning.cnf" >/dev/null
[mysqld]
skip-name-resolve = 1
performance_schema = OFF
innodb_flush_method = O_DIRECT
EOF

echo "==> 启动 MySQL 容器（含CPU/内存资源限制、健康检查、持久卷）"
sudo docker run -d \
  --name "${CONTAINER_NAME}" \
  --restart unless-stopped \
  --cpus="${CPUS}" \
  --cpuset-cpus="${CPUSET}" \
  --memory="${MEM_LIMIT}" \
  --memory-reservation="${MEM_RESERVATION}" \
  --memory-swap="${MEM_SWAP}" \
  --oom-kill-disable \
  --cpu-shares="2048" \
  --ulimit nofile="${NOFILE_SOFT}:${NOFILE_HARD}" \
  --health-cmd="mysqladmin --defaults-file=/etc/mysql/conf.d/client.cnf ping || exit 1" \
  --health-interval="${HEALTH_INTERVAL}" \
  --health-timeout="${HEALTH_TIMEOUT}" \
  --health-retries="${HEALTH_RETRIES}" \
  --tmpfs /tmp:rw,noexec,nosuid,size=512m \
  -e MYSQL_ROOT_PASSWORD="${ROOT_PASSWORD}" \
  -p "${HOST_PORT}:3306" \
  -v "${DATA_DIR}:/var/lib/mysql" \
  -v "${CONF_DIR}:/etc/mysql/conf.d" \
  -v "${LOG_DIR}:/var/log/mysql" \
  "${MYSQL_IMAGE}" \
  --innodb_buffer_pool_size="${INNODB_BUFFER_POOL_SIZE}" \
  --innodb_log_file_size="${INNODB_LOG_FILE_SIZE}" \
  --innodb_flush_log_at_trx_commit=1 \
  --max_connections="${MAX_CONNECTIONS}" \
  --server-id=1 \
  --log_bin=/var/lib/mysql/mysql-bin \
  --binlog_expire_logs_seconds="${BINLOG_EXPIRE_SECONDS}"

echo "==> 等待容器健康就绪"
for i in {1..60}; do
  hs="$(sudo docker inspect --format='{{json .State.Health.Status}}' "${CONTAINER_NAME}" 2>/dev/null || echo null)"
  if [[ "${hs}" == "\"healthy\"" ]]; then
    echo "容器已就绪: healthy"
    break
  fi
  sleep 2
done

echo "==> 设置每日3:05 自动备份（保存在 ${BACKUP_DIR}）"
CRON_FILE="/etc/cron.d/docker-mysql-backup"
CRON_CMD="docker exec ${CONTAINER_NAME} sh -lc 'mysqldump -uroot -p\"\\$MYSQL_ROOT_PASSWORD\" --all-databases --single-transaction --routines --events' > ${BACKUP_DIR}/mysql-\$(date +\\%F).sql"
echo "5 3 * * * root ${CRON_CMD}" | sudo tee "${CRON_FILE}" >/dev/null || true
sudo chmod 0644 "${CRON_FILE}" || true
if command -v systemctl >/dev/null 2>&1; then
  sudo systemctl restart crond 2>/dev/null || sudo systemctl restart cron 2>/dev/null || true
fi

echo "==> 校正数据目录属主（容器启动后可能调整为 999:999）"
# 允许失败，因不同镜像UID/GID可能不同
set +e
sudo chown -R 999:999 "${DATA_DIR}" "${CONF_DIR}" "${LOG_DIR}"
set -e

cat <<EOM

✅ 安装完成
- 容器: ${CONTAINER_NAME}
- 监听端口: ${HOST_PORT}
- 数据目录: ${DATA_DIR}
- 备份目录: ${BACKUP_DIR}
- MySQL root 密码: 123456
- 资源: CPU=${CPUS} (绑定 ${CPUSET}), 内存上限=${MEM_LIMIT}, 预留=${MEM_RESERVATION}

常用命令:
  查看日志:      sudo docker logs --tail=200 ${CONTAINER_NAME}
  进容器:        sudo docker exec -it ${CONTAINER_NAME} bash
  健康状态:      sudo docker inspect --format='{{.State.Health.Status}}' ${CONTAINER_NAME}
  立即备份:      sudo docker exec -i ${CONTAINER_NAME} sh -lc 'mysqldump -uroot -p"\$MYSQL_ROOT_PASSWORD" --all-databases --single-transaction --routines --events' > ${BACKUP_DIR}/manual-\$(date +%F-%H%M%S).sql

EOM